home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 283_01 / clairol.c < prev    next >
C/C++ Source or Header  |  1988-12-07  |  12KB  |  453 lines

  1.  
  2.  
  3. #include "ciao.h"
  4. #include "keys.h"
  5.  
  6. /*
  7. **  clairol()  - modify screen colors or monochrome attributes "on the fly"
  8. **               popout window, updates previous screen on exit
  9. **               to reflect the newly selected values
  10. **
  11. **               returns on Control-C, resets to SIG_DFL, restores screen
  12. **    4/23/88, dco -- removed signal code, doesn't belong in service routine!
  13. */
  14.  
  15.      /* Note:  Users who select a PLAIN screen create ambiguity */
  16.      /*        between the various message levels.  The NEXT    */
  17.      /*        time clairol() is called, the ambiguous colors   */
  18.      /*        default to the lower message level.  For example */
  19.      /*        if Normal and Bold have the same value on entry, */
  20.      /*        and the user changes the value of EITHER, BOTH   */
  21.      /*        Normal and Bold bytes in the screen buffer will  */
  22.      /*        be reset to the NEW NORMAL value.  This is       */
  23.      /*        because INFORMATION HAS BEEN LOST concerning the */
  24.      /*        meaning of the message levels, in the step where */
  25.      /*        user selected a PLAIN screen.                    */
  26.      /*                                                         */
  27.      /*        You should test the ambiguity flag on exit from  */
  28.      /*        clairol(), and take whatever corrective action   */
  29.      /*        is needed thereafter.                            */
  30.      /*                                                         */
  31.      /*        In cases where your program cannot tolerate the  */
  32.      /*        ambiguity a user MIGHT create (the possibility   */
  33.      /*        is there!), you should use video registers 4     */
  34.      /*        through 15, which clairol() does not alter, and  */
  35.      /*        to which users have no access; or else simply    */
  36.      /*        don't call clairol()...!  Clairol() gives the    */
  37.      /*        user permission to change things you may not     */
  38.      /*        want to be changed, in other words.              */
  39.  
  40.  
  41. #define MONOCHROME 7
  42.  
  43. int ambiguity = 0;
  44.  
  45. static void test_ambiguity()
  46. {
  47.      static int i, j;
  48.  
  49.      for ( ambiguity = i = 0; i < 3; i++ )
  50.      {
  51.          for ( j = i + 1; j < 4; j++ )
  52.          {
  53.              ambiguity |= vid[i] == vid[j]; 
  54.          }
  55.      }
  56. }
  57.  
  58.  
  59.  
  60. /*
  61. static jmp_buf remark;
  62. */
  63. static int ch, tx, ty, which, eaSave, edSave, icon, flipflop,
  64.            nrmSave, bldSave, empSave, ntcSave;
  65.  
  66.  
  67. /*
  68. static void ControlC()
  69. {
  70.       longjmp(remark,-1); 
  71. }
  72. */
  73.  
  74.  
  75. static void valSave()
  76. {
  77.       test_ambiguity();         /* detect plain screen */
  78.  
  79.       nrmSave = vid[0] & 0xFF;  /* normal       Vid_init() defines only these */
  80.       bldSave = vid[1] & 0xFF;  /* bold         four values for color text.   */
  81.       empSave = vid[2] & 0xFF;  /* emphasis     Programs may alter all 16     */
  82.       ntcSave = vid[3] & 0xFF;  /* notice       values of vid[], of course.   */
  83.  
  84.       eaSave  = vid[10] & 0xFF;
  85.       edSave  = vid[13] & 0xFF;
  86.       vid[10] = 0x0F;
  87.       vid[13] = 0x07;
  88. }
  89.  
  90.  
  91. static void reset()
  92. {
  93.       setwindow( tx, ty, tx + 3, ty + 5 );
  94.       wputs("^φ");
  95.       clrwindow();
  96.       setwindow( tx, ty, tx + 14, ty + 5 );
  97.       gotoxy(4,1);
  98.       wputs("^0Normal    ^φ");
  99.       gotoxy(4,2);
  100.       wputs("^1Bold      ^φ");
  101.       gotoxy(4,3);
  102.       wputs("^2Emphasis  ^φ");
  103.       gotoxy(4,4);
  104.       wputs("^3Attention!^φ");
  105. }
  106.  
  107.  
  108. static void position( line ) int line;
  109. {
  110.       reset();
  111.       gotoxy( 1,0 + line );
  112.       wink( 24 );
  113.       gotoxy( 2,1 + line );
  114.       wink( 26 );
  115.       gotoxy( 1,2 + line );
  116.       wink( 25 );
  117.       gotoxy( 0,1 + line );
  118.       wink( 27 );
  119.       gotoxy( 1,1 + line );
  120.  
  121.       wprintf("^Ω%c^φ",icon);;
  122. }
  123.  
  124.  
  125. static void normPos()
  126. {
  127.       position(0);
  128. }
  129.  
  130.  
  131. static void boldPos()
  132. {
  133.       position(1);
  134. }
  135.  
  136.  
  137. static void emphPos()
  138. {
  139.       position(2);
  140. }
  141.  
  142.  
  143. static void notePos()
  144. {
  145.       position(3);
  146. }
  147.  
  148.  
  149. static void pause()
  150. {
  151.       static int n;
  152.       for (n = 380; n; n--) if (kbhit()) break;
  153. }
  154.  
  155.  
  156. static void waitforuser()
  157. {
  158.       int flag;
  159.       flag = 0;
  160.       while (1)
  161.       {
  162.           icon = flag? 'K':'?'; normPos(); pause();
  163.           icon = flag? 'E':'A'; boldPos(); pause();
  164.           icon = flag? 'Y':'N'; emphPos(); pause();
  165.           icon = flag?  19:'Y'; notePos(); pause();
  166.           if (kbhit()) break;
  167.           else flag ^= 1;
  168.       }
  169.       while (kbhit()) getch();
  170.       icon = '?';
  171. }
  172.  
  173.  
  174. static void help()
  175. {
  176.       int k;
  177.       static char *p, *msg[] = { "re", "ob", "in" };
  178.  
  179.       if (video.mode == MONOCHROME) p = msg[0]; /* absolute */
  180.       else p = flipflop? msg[1]: msg[2];
  181.  
  182.       wputs("^φ");
  183.       clrwindow();
  184.       wputs("^ΩF10^φ  help\n");
  185.       wprintf("^Ω%c%c%c%c^φ select\n",27,24,25,26);
  186.       wputs("^ΩF1^φ   bright\n");
  187.       wputs("^ΩF2^φ   blink\n");
  188.       wprintf("^ΩF9^φ   %sverse\n", p);
  189.       wputs("^ΩESC^φ  done!");
  190.       for (k = 20; k; k-- ) pause();
  191.       if (kbhit()) ch = keyin( screenwait ); else ch = '?';
  192.       clrwindow();
  193. }
  194.  
  195.  
  196.  
  197.  
  198. /*  The Monochrome Adapter case is simple... */
  199.  
  200.  
  201. static void mono()
  202. {
  203.       int ix, hibyte, lobyte, hibit, lobit;
  204.  
  205.       ix = which;
  206.       lobyte = vid[ ix ] & 0x07;  /* foreground color? */
  207.  
  208.       /* preserve status of blink and bright bits */
  209.  
  210.       lobit  = vid[ ix ] & 0x08;  /* intensity bit?    */
  211.       hibit  = vid[ ix ] & 0x80;  /* blink bit?        */
  212.  
  213.       hibyte = 0;
  214.       if (lobyte == 0) /* turn off reverse, turn on underline */
  215.       {
  216.              lobyte = 0x01;
  217.       }
  218.       else if (lobyte == 1) /* turn off underline, turn on normal */
  219.       {
  220.              lobyte = 0x07;
  221.       }
  222.       else /* turn off normal, turn on reverse */
  223.       {
  224.              lobyte = 0x00;
  225.              hibyte = 0x70;
  226.       }
  227.  
  228.       vid[ ix ] = hibyte | hibit | lobyte | lobit;
  229. }
  230.  
  231.  
  232.  
  233. /* The Color/Graphics Adapter case is even simpler...! */
  234.  
  235.  
  236. static void cgaright()
  237. {
  238.       int ix, hibyte, lobyte, hibit, lobit;
  239.  
  240.       ix = which;
  241.       lobyte = vid[ ix ] & 0x07;  /* foreground color? */
  242.       hibyte = vid[ ix ] & 0x70;  /* background color? */
  243.  
  244.       /* preserve status of blink and bright bits */
  245.  
  246.       lobit  = vid[ ix ] & 0x08;  /* intensity bit?    */
  247.       hibit  = vid[ ix ] & 0x80;  /* blink bit?        */
  248.  
  249.       if (flipflop)
  250.       {
  251.           hibyte += 0x10;
  252.           if (hibyte > 0x70) hibyte = 0;
  253.       }
  254.       else
  255.       {
  256.           ++lobyte;
  257.           if (lobyte > 7) lobyte = 0;
  258.       }
  259.       vid[ ix ] = hibyte | hibit | lobyte | lobit;
  260. }
  261.  
  262.  
  263. static void cgaleft()
  264. {
  265.       int ix, hibyte, lobyte, hibit, lobit;
  266.  
  267.       ix = which;
  268.       lobyte = vid[ ix ] & 0x07;  /* foreground color? */
  269.       hibyte = vid[ ix ] & 0x70;  /* background color? */
  270.  
  271.       /* preserve status of blink and bright bits */
  272.  
  273.       lobit  = vid[ ix ] & 0x08;  /* intensity bit?    */
  274.       hibit  = vid[ ix ] & 0x80;  /* blink bit?        */
  275.  
  276.       if (flipflop)
  277.       {
  278.           hibyte -= 0x10;
  279.           if (hibyte < 0) hibyte = 0x70;
  280.       }
  281.       else
  282.       {
  283.           --lobyte;
  284.           if (lobyte < 0) lobyte = 7;
  285.       }
  286.       vid[ ix ] = hibyte | hibit | lobyte | lobit;
  287. }
  288.  
  289.  
  290.  
  291.  
  292. static void inquire()
  293. {
  294.       unsigned bl, bt, flip;
  295.  
  296.       flipflop = which = 0;
  297.       while (ch != 27)
  298.       {
  299.             position( which );
  300.             ch = keyin( screenwait );
  301.             switch ( ch )
  302.             {
  303.                case  ESC:
  304.                {
  305.                     return;
  306.                }
  307.                case F1:    /* F1?  bright */
  308.                {
  309.                     vid[ which ] ^= 0x08;  /* toggle intensity bit */
  310.                     break;
  311.                }
  312.                case F2:    /* F2?  blink */
  313.                {
  314.                     vid[ which ] ^= 0x80;  /* toggle blink bit */
  315.                     break;
  316.                }
  317.                case F9:    /* F9?  reverse, or obverse/inverse */
  318.                {
  319.                     if (video.mode == MONOCHROME)
  320.                     {
  321.                          flip = vid[ which ] & 0x07;  /* read foreg